package servlets.site;

import beans.AddressFacade;
import beans.VideoGameFacade;
import beans.CartLineFacade;
import beans.CartFacade;
import beans.CommentFacade;
import beans.NoteFacade;
import beans.UserFacade;
import entities.Adresse;
import entities.Comment;
import entities.JeuVideo;
import entities.LigneDePanier;
import entities.Note;
import entities.Panier;
import entities.Utilisateur;
import helpers.ServletHelper;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/*
 *  Cette servlet contient tout les traitements liés aux appels AJAX
 */
@WebServlet(name = "AjaxServlet", urlPatterns = {"/AjaxServlet"})
public class AjaxServlet extends HttpServlet {

    ///////////////////// LES GESTIONNAIRES ////////////////////
    @EJB
    private UserFacade userFacade;
    @EJB
    private AddressFacade addressFacade;
    @EJB
    private VideoGameFacade videoGameFacade;
    @EJB
    private CartFacade cartFacade;
    @EJB
    private CartLineFacade cartLineFacade;
    @EJB
    private CommentFacade commentFacade;
    @EJB
    private NoteFacade noteFacade;
    ////////////////////////////////////////////////////////////

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException, ParseException {
        response.setContentType("text/html; charset=UTF-8");
        PrintWriter out = response.getWriter();
        String action = request.getParameter("action");
        HttpSession session = request.getSession();
        // Message d'erreur
        String invalide = "<img src=\"images/errorIcon.png\" width=\"16\" />";
        String alreadyUse = "<b style=\"color: red\">Already in use</b>";
        String valide = "<img src=\"images/checkIcon.png\" width=\"16\" />";
        String UnknownAddress = "<b style=\"color: red\">Unknown Email</b>";
        String wrongPassword = "<b style=\"color: red\">Wrong Password</b>";
        Utilisateur user;

        if (action != null) {

            // ici on vérifie que l'email n'est pas déjà utilisé en cherchant dans la BD un utilisateur par son email.
            if (action.equals("createAccount") || action.equals("login")) {
                String email = request.getParameter("email");
                user = userFacade.getByEmail(email);

                // si l'email est correct
                if (email == null || email.isEmpty()) {
                    out.print(invalide);

                    // si l'email existe,
                } else if (user != null) {
                    // si c'est une connexion, on envoie dans le flux un message de validation
                    if (action.equals("login")) {
                        out.print(valide);
                        // si c'est une inscription, on envoie dans le flux un message d'erreur
                    } else if (action.equals("createAccount")) {
                        out.print(invalide);
                        out.print(alreadyUse);
                    }

                    // si l'email n'existe pas ,
                } else {
                    // si c'est une connexion, on envoie dans le flux un message d'erreur
                    if (action.equals("login")) {
                        out.print(invalide);
                        out.print(UnknownAddress);
                        // si c'est une connexion, on envoie dans le flux un message de validation
                    } else if (action.equals("createAccount")) {
                        out.print(valide);
                    }
                }

                // Creation du compte
            } else if (action.equals("validateCreateAccount")) {
                // récupération des parametres
                String email = request.getParameter("email");
                String password = request.getParameter("password");
                String nom = request.getParameter("lastName");
                String prenom = request.getParameter("firstName");

                // Si les parametres ne sont pas null et pas vide
                if (ServletHelper.verifyStrings(email, password, nom, prenom)) {
                    user = userFacade.getByEmail(email);

                    // Si l'identifiant n'existe pas, on créé le compte et on associe un panier à l'utilisateur
                    if (user == null) {
                        user = userFacade.create(email, password, nom, prenom);
                        user.setPanier(cartFacade.create());
                        userFacade.edit(user);
                        session.setAttribute("utilisateur", user);
                        out.print("true");

                        // Sinon on ne créer pas l'utilisateur
                    } else {
                        out.print("false");
                    }
                    // Sinon on ne créer pas l'utilisateur
                } else {
                    out.print("false");
                }

                // vérification du mot de passe dans la BD
            } else if (action.equals("loginPassword")) {
                // récupération des parametres
                String password = request.getParameter("password2");
                String email = request.getParameter("email2");
                // Si les parametres ne sont pas null et pas vide
                if (ServletHelper.verifyStrings(email, password)) {
                    Utilisateur u = userFacade.getByEmail(email);
                    // si le mot de passe est bon, on envoie dans le flux un message de validation
                    if (u != null && u.getMotDePasse().equals(password)) {
                        out.print(valide);
                        // si c'est une connexion, on envoie dans le flux un message d'erreur
                    } else {
                        out.print(invalide);
                        out.print(wrongPassword);
                    }
                } else {
                    out.print(invalide);
                    out.print(wrongPassword);
                }
                // connexion
            } else if (action.equals("validateLogin")) {
                // récupération des parametres
                String email = request.getParameter("email2");
                String password = request.getParameter("password2");
                // Si les parametres ne sont pas null et pas vide
                if (ServletHelper.verifyStrings(email, password)) {
                    user = userFacade.getByEmail(email);
                    // si l'utilisateur n'existe pas dans la BD, on envoie dans le flux un message d'erreur
                    if (user == null) {
                        out.print("false");
                        // s'il existe,
                    } else {
                        // et que le mot de passe est bon, on ouvre une session pour cette utilisateur
                        if (user.getMotDePasse().equals(password)) {
                            session.setAttribute("utilisateur", user);
                            out.print("true");
                            // sinon on envoie un message d'erreur
                        } else {
                            out.print("false");
                        }
                    }
                    // sinon on envoie un message d'erreur
                } else {
                    out.print("false");
                }

                // Mise à jour des informations de l'utilisateur
            } else if (action.startsWith("update")) {
                // récupération des parametres
                String[] parametres = action.split("_");
                String champ = parametres[1];
                String value = request.getParameter("value");
                value = value.trim();
                user = (Utilisateur) session.getAttribute("utilisateur");
                user = userFacade.find(user.getId());
                String adresseID = null;
                Adresse a = null;
                if (parametres.length == 3) {
                    adresseID = parametres[2];
                    a = addressFacade.find(Integer.parseInt(adresseID));
                }

                // Si la valeur n'est pas vide, on modifie les champ
                if (!value.isEmpty()) {
                    // S'il n'y a pas de parametre adresseID, on modifie les informations de l'utilisateur
                    if (adresseID == null) {
                        if (champ.equals("Firstname")) {
                            user.setPrenom(value);
                        } else if (champ.equals("Lastname")) {
                            user.setNom(value);
                        } else if (champ.equals("Email")) {
                            Utilisateur v = userFacade.getByEmail(value);
                            if (v == null) {
                                user.setEmail(value);
                            } else {
                                value = user.getEmail();
                            }
                        } else if (champ.equals("Date")) {
                            SimpleDateFormat date = new SimpleDateFormat("MM/dd/yyyy");
                            user.setDateDeNaissance(date.parse(value));
                        }
                        userFacade.edit(user);
                        // Sinon, on modifie l'adresse de l'utilisateur
                    } else {
                        if (champ.equals("Pays")) {
                            a.setPays(value);
                        } else if (champ.equals("Ville")) {
                            a.setVille(value);
                        } else if (champ.equals("Rue")) {
                            a.setRue(value);
                        } else if (champ.equals("CodePostal")) {
                            a.setCodePostal(value);
                        }
                        addressFacade.edit(a);
                    }
                    // modification de la variable de session
                    session.setAttribute("utilisateur", userFacade.find(user.getId()));
                    out.print(value);
                    // si la valeur envoyée est vide, alors on renvoie les données initiales
                } else {
                    if (champ.equals("Firstname")) {
                        out.print(user.getPrenom());
                    } else if (champ.equals("Lastname")) {
                        out.print(user.getNom());
                    } else if (champ.equals("Email")) {
                        out.print(user.getEmail());
                    } else if (champ.equals("Date")) {
                        out.print(user.getDateDeNaissance());
                    } else if (champ.equals("Pays")) {
                        out.print(a.getPays());
                    } else if (champ.equals("Ville")) {
                        out.print(a.getVille());
                    } else if (champ.equals("Rue")) {
                        out.print(a.getRue());
                    } else if (champ.equals("CodePostal")) {
                        out.print(a.getCodePostal());
                    }
                }

                // Suppression d'un adresse d'utilisateur
            } else if (action.equals("deleteAddress")) {
                // récupération des parametres
                int addressID = ServletHelper.getIntegerValue(request.getParameter("id"));

                if (addressID > 0) {
                    // suppression de l'adresse
                    Adresse address = addressFacade.find(addressID);
                    user = (Utilisateur) session.getAttribute("utilisateur");
                    userFacade.removeAddress(user, address);
                    // modification de la variable de session
                    //s.setAttribute("utilisateur", userFacade.find(u.getId()));
                }

                // Ajout d'un article au panier
            } else if (action.equals("addToCart")) {
                // On récupère l'id du jeu à ajouter
                int id = ServletHelper.getIntegerValue(request.getParameter("jeuvideoId"));
                Utilisateur u = (Utilisateur) session.getAttribute("utilisateur");
                // Si l'id est valide, on récupére les données du panier de l'utilisateur
                if (id > 0) {
                    JeuVideo jv = videoGameFacade.find(id);
                    Panier p = u.getPanier();
                    LigneDePanier lp = cartLineFacade.getByUserCart(p, jv);
                    // Si le jeu n'est pas dans le panier alors on ajoute une ligne au panier
                    if (lp == null) {
                        cartFacade.addVideoGame(p, jv);
                        // sinon,  on modifie la quantite de la ligne du panier
                    } else {
                        cartLineFacade.updateQuantity(lp);
                    }
                    userFacade.edit(u);
                    u = userFacade.find(u.getId());
                    session.setAttribute("utilisateur", u);

                    double total = 0;
                    for (LigneDePanier ldp : u.getPanier().getLigneDePanier()) {
                        total += ldp.getJeuVideo().getPrice() * ldp.getQuantite();
                    }
                    out.print(ServletHelper.roundTwoDecimals(total));
                }

                // Suppression d'un article dans la panier
            } else if (action.equals("dropProduct")) {
                // on récupérer l'article à supprimer
                String id = request.getParameter("jeuVideoId");
                JeuVideo jv = videoGameFacade.find(ServletHelper.getIntegerValue(id));
                // on récupère le paneir de l'utilisateur
                Utilisateur u = (Utilisateur) session.getAttribute("utilisateur");
                Panier p = u.getPanier();
                // on supprime l'article du panier
                cartFacade.removeVideoGame(p, jv);
                userFacade.edit(u);
                u = userFacade.find(u.getId());
                session.setAttribute("utilisateur", u);

                double total = 0;
                for (LigneDePanier ldp : u.getPanier().getLigneDePanier()) {
                    total += ldp.getJeuVideo().getPrice() * ldp.getQuantite();
                }
                out.print(ServletHelper.roundTwoDecimals(total));

                // Mise a jour du mot de passe
            } else if (action.equals("changePassword")) {
                // on récupère les parametres
                String password = request.getParameter("password");
                String rePassword = request.getParameter("repassword");
                Utilisateur u = (Utilisateur) session.getAttribute("utilisateur");
                // si le mot de passe est bon, l'utilisateur peut modifier sont mot de passe
                if (u.getMotDePasse().equals(password)) {
                    u.setMotDePasse(rePassword);
                    userFacade.edit(u);
                }
                session.setAttribute("utilisateur", userFacade.find(u.getId()));

                // Modification de la quantite d'un article du panier
            } else if (action.equals("changeQuantity")) {
                // récupération des parameteres
                int id = ServletHelper.getIntegerValue(request.getParameter("ligneDePanier"));

                if (id > 0) {
                    int quantite = ServletHelper.getIntegerValue(request.getParameter("quantity"));
                    Utilisateur u = (Utilisateur) session.getAttribute("utilisateur");
                    // on récupère la ligne du panier et on met à jour la quantité
                    LigneDePanier lp = cartLineFacade.find(id);
                    cartLineFacade.updateQuantity(lp, quantite);
                    userFacade.edit(u);
                    u = userFacade.find(u.getId());
                    session.setAttribute("utilisateur", u);

                    double sousTotal = lp.getJeuVideo().getPrice() * lp.getQuantite();
                    double total = 0;
                    for (LigneDePanier ldp : u.getPanier().getLigneDePanier()) {
                        total += ldp.getJeuVideo().getPrice() * ldp.getQuantite();
                    }
                    out.print(ServletHelper.roundTwoDecimals(sousTotal) + "_" + ServletHelper.roundTwoDecimals(total));
                }

            }  else if (action.equals("addComments")) {
                String comment = request.getParameter("comment");
                String idJeuVideo = request.getParameter("idJeuVideo");
                String ratingValue = request.getParameter("value");
                user = (Utilisateur) session.getAttribute("utilisateur");

                if (ServletHelper.verifyStrings(ratingValue, comment, idJeuVideo)) {
                    JeuVideo videoGame = videoGameFacade.find(ServletHelper.getIntegerValue(idJeuVideo));
                    Note note = new Note(ServletHelper.getIntegerValue(ratingValue));
                    Comment com = new Comment(user, comment, note);
                    videoGameFacade.addComment(com, videoGame);
                    out.print(videoGameFacade.getAverageNote(videoGame));
                }
            }
        }
        
        out.close();
    }
// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">

    /**
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException,
            IOException {
        try {
            processRequest(request, response);
        } catch (ParseException ex) {
            Logger.getLogger(AjaxServlet.class.getName()).log(Level.SEVERE, null, ex);
        }




    }

    /**
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException,
            IOException {
        try {
            processRequest(request, response);
        } catch (ParseException ex) {
            Logger.getLogger(AjaxServlet.class.getName()).log(Level.SEVERE, null, ex);
        }




    }

    /**
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";


    }// </editor-fold>
}
